"""
Test Configuration for TaskMaster v1
AceFlow v3.0 - Integration Test Phase

Shared test fixtures and configuration
"""

import pytest
import os
import tempfile
import sys
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.testclient import TestClient

# Add backend directory to path
backend_dir = os.path.dirname(os.path.dirname(__file__))
sys.path.insert(0, backend_dir)

from app.models.database import DatabaseManager
from app.api.auth import router as auth_router
from app.api.tasks import router as tasks_router


def create_test_app():
    """Create a test FastAPI application"""
    app = FastAPI(
        title="TaskMaster v1 - Test",
        description="多用户隔离个人任务管理系统 - 测试环境",
        version="1.0.0",
    )

    # Configure CORS
    app.add_middleware(
        CORSMiddleware,
        allow_origins=["*"],
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )

    # Include API routers
    app.include_router(
        auth_router,
        prefix="/api/auth",
        tags=["Authentication"]
    )

    app.include_router(
        tasks_router,
        prefix="/api/tasks",
        tags=["Tasks"]
    )

    @app.get("/")
    async def root():
        """Root endpoint"""
        return {
            "message": "TaskMaster v1 API - Test",
            "version": "1.0.0",
            "status": "test"
        }

    @app.get("/health")
    async def health_check():
        """Health check endpoint"""
        return {
            "status": "healthy",
            "environment": "test"
        }

    return app


@pytest.fixture(scope="session")
def test_db_path():
    """Create temporary database for testing"""
    # Use ASCII-only path to avoid Unicode issues
    temp_dir = os.path.join(tempfile.gettempdir(), "taskmaster_test")
    os.makedirs(temp_dir, exist_ok=True)
    db_path = os.path.join(temp_dir, "test.db")
    yield db_path
    # Cleanup
    if os.path.exists(db_path):
        os.unlink(db_path)
    if os.path.exists(temp_dir):
        os.rmdir(temp_dir)


@pytest.fixture(scope="session")
def test_db_manager(test_db_path):
    """Test database manager instance"""
    db_manager = DatabaseManager(test_db_path)
    yield db_manager
    # Cleanup will be handled by test_db_path fixture


@pytest.fixture
def test_client(test_db_manager):
    """FastAPI test client"""
    # Override the global database manager for testing
    import app.services.user_service
    import app.services.task_service
    import app.models.database

    # Store original instances
    original_db_manager = app.models.database.db_manager
    original_user_service = app.services.user_service.user_service
    original_task_service = app.services.task_service.task_service

    try:
        # Replace with test instances
        app.models.database.db_manager = test_db_manager
        app.services.user_service.user_service = app.services.user_service.UserService()
        app.services.task_service.task_service = app.services.task_service.TaskService()

        # Create test app
        test_app = create_test_app()
        with TestClient(test_app) as client:
            yield client
    finally:
        # Restore original instances
        app.models.database.db_manager = original_db_manager
        app.services.user_service.user_service = original_user_service
        app.services.task_service.task_service = original_task_service


@pytest.fixture
def test_user_data():
    """Test user data"""
    import uuid
    unique_id = str(uuid.uuid4())[:8]
    return {
        "username": f"testuser_{unique_id}",
        "password": "testpass123",
        "email": f"test_{unique_id}@example.com"
    }


@pytest.fixture
def test_task_data():
    """Test task data"""
    return {
        "title": "Test Task",
        "description": "Test Description",
        "due_date": "2025-09-15T10:00:00",
        "priority": 2
    }


@pytest.fixture
def registered_user(test_client, test_user_data):
    """Create and return a registered user"""
    response = test_client.post("/api/auth/register", json=test_user_data)
    assert response.status_code == 200
    assert response.json()["success"] is True

    return {
        "user_data": test_user_data,
        "user_id": response.json()["user_id"]
    }


@pytest.fixture
def auth_token(test_client, registered_user):
    """Get authentication token for registered user"""
    login_data = {
        "username": registered_user["user_data"]["username"],
        "password": registered_user["user_data"]["password"]
    }

    response = test_client.post("/api/auth/login", json=login_data)
    assert response.status_code == 200
    assert response.json()["success"] is True

    return response.json()["token"]


@pytest.fixture
def auth_headers(auth_token):
    """Authentication headers for API requests"""
    return {"Authorization": f"Bearer {auth_token}"}


@pytest.fixture
def sample_task(test_client, auth_headers, test_task_data):
    """Create and return a sample task"""
    response = test_client.post("/api/tasks", json=test_task_data, headers=auth_headers)
    assert response.status_code == 200
    assert response.json()["success"] is True

    task_id = response.json()["task_id"]

    # Get the created task
    response = test_client.get(f"/api/tasks/{task_id}", headers=auth_headers)
    assert response.status_code == 200

    return response.json()


# Test data constants
TEST_USERS = [
    {
        "username": "testuser1",
        "password": "testpass123",
        "email": "test1@example.com"
    },
    {
        "username": "testuser2",
        "password": "testpass456",
        "email": "test2@example.com"
    },
    {
        "username": "testuser3",
        "password": "testpass789",
        "email": "test3@example.com"
    }
]

TEST_TASKS = [
    {
        "title": "High Priority Task",
        "description": "This is a high priority task",
        "due_date": "2025-09-10T10:00:00",
        "priority": 1
    },
    {
        "title": "Medium Priority Task",
        "description": "This is a medium priority task",
        "due_date": "2025-09-15T14:00:00",
        "priority": 2
    },
    {
        "title": "Low Priority Task",
        "description": "This is a low priority task",
        "due_date": "2025-09-20T16:00:00",
        "priority": 3
    }
]
